using System;
using BRozklad.GAs;
using System.Collections;
using System.Data;
/*
 * Potribno stvoryty Interface u jakomu ogoloshyty ti metody, jaki poznachyni standart
 * i cej klas (Rozklad) porvynen nasliduvaty vin cjogo Interface'u
 * 
 * 
 * Takoz potribno strovyty class Para i popravyty dejaki chastyny cjogo kodu
 */


namespace BRozklad
{
    class Rozklad
    {

        public static int par = 200;
        public static int polejnaparu = 6;

        private int size;
        private int[,] rozklad;    //[par][polejnaparu]  pole 0 - ID pary; 1 - ID grupy; 2 - ID vykldacha; 3 - ID kimnaty; 4 - chas; 5 - kilk

        public Rozklad()
        {
            rozklad = new int[par, polejnaparu];
        }
        bool NotNew(int index)    //standart - for para
        {
            int j;
            for (int i = 0; i < index; i++)
            {
                for (j = 0; j < polejnaparu && rozklad[i, j] == rozklad[index, j]; j++) ;
                if (j == polejnaparu)
                    return true;
            }
            return false;
        }
        private void GenerateRandomPara(int index, DataSet rozkladDataSet, Random rand)
        {
            Configuration.iii++;
            int r;
            rozklad[index, 0] = Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[index][0]);
            r = rand.Next(rozkladDataSet.Tables["DifferentGroupe"].Rows.Count);
            rozklad[index, 1] = Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[index][1]);
//            rozklad[index, 1] = (int)rozkladDataSet.DifferentGroupe.Rows[r][0];
            if (Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[index][6]) == 0)
            {
                ArrayList al = new ArrayList();
                int sizeTeach = Convert.ToInt32(rozkladDataSet.Tables["TeacherSubject"].Rows.Count);
                for (int i = 0; i < sizeTeach; i++)
                {
                    if (Convert.ToInt32(rozkladDataSet.Tables["TeacherSubject"].Rows[i][2]) == Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[index][2]))
                    {
                        al.Add(Convert.ToInt32(rozkladDataSet.Tables["TeacherSubject"].Rows[i][1]));
                    }
                }
                r = rand.Next(al.Count);
                rozklad[index, 2] = (int)al[r];
            }
            else
            {
                rozklad[index,2] = Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[index][6]);
            }

            if (Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[index][5]) == 0)
            {
                int kk = 0;
                while (Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[kk][0]) != rozklad[index, 0])
                    kk++;
                int type = Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[kk][3]);
                string stype = "";
                if (type == 1)
                {
                    stype = "Auditoria";
                }
                else
                {
                    stype = "Laboratoria";
                }
                ArrayList al = new ArrayList();
                int sizeAud = Convert.ToInt32(rozkladDataSet.Tables["Auditorias"].Rows.Count);
                for (int i = 0; i < sizeAud; i++)
                {
                    if (rozkladDataSet.Tables["Auditorias"].Rows[i][1].ToString() == stype)
                        al.Add(Convert.ToInt32(rozkladDataSet.Tables["Auditorias"].Rows[i][0]));
                }
                r = rand.Next(al.Count);
                rozklad[index, 3] = (int)al[r];
            }
            else
            {
                rozklad[index, 3] = Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[index][5]);
            }

            if (Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[index][7]) == 0)
            {
                r = rand.Next(rozkladDataSet.Tables["Times"].Rows.Count);
                rozklad[index, 4] = Convert.ToInt32(rozkladDataSet.Tables["Times"].Rows[r][0]);
            }
            else
            {
                rozklad[index, 4] = Convert.ToInt32(rozkladDataSet.Tables["Paras"].Rows[index][7]);
            }

            double kkkk = Convert.ToDouble(rozkladDataSet.Tables["Paras"].Rows[index][4]);
            rozklad[index, 5] = (int)(kkkk * 2);
        }
        public void StartGenerate(object inrozkladDataSet)    //standart
        {
            DataSet rozkladDataSet = (DataSet)inrozkladDataSet;
            Random rand = Configuration.rand;
            
            size = rozkladDataSet.Tables["Paras"].Rows.Count;
            for (int i = 0; i < size; i++)
            {
                GenerateRandomPara(i, rozkladDataSet, rand);
                if (NotNew(i))                  //mozhe lyshne????
                    i--;
            }
        }

        private void copy_para_DEMO(int index, Rozklad inrozklad)
        {
            for (int i = 0; i < polejnaparu; i++)
            {
                rozklad[index, i] = inrozklad.rozklad[index, i];
            }
        }
        public void NextGenerate(object inrozklad, object inrozkladDataSet)  //TODO: const   //standart
        {
            Rozklad rozklad = (Rozklad)inrozklad;
            DataSet rozkladDataSet = (DataSet)inrozkladDataSet;
            Random rand = Configuration.rand;
            int r;
            for (int i = 0; i < size; i++)
            {
                r = rand.Next(10);
                if (r == 1)
                {
                    GenerateRandomPara(i, rozkladDataSet, rand);
                }
                else
                {
                    copy_para_DEMO(i, rozklad);
                }
            }
        }
        private int GetCostFromSelect()
        {
            int res = 0;
            WorkWithDB wwdb = new WorkWithDB();
            wwdb.InsertToCur(this);
            for (int i = 0; i < Population.rozkladDataSet.Tables["SelectsForCost"].Rows.Count; i++)
            {
                if (Convert.ToBoolean(Population.rozkladDataSet.Tables["SelectsForCost"].Rows[i][4]) == true)
                    res += wwdb.GetCount((string)(Population.rozkladDataSet.Tables["SelectsForCost"].Rows[i][2])) * Convert.ToInt32(Population.rozkladDataSet.Tables["SelectsForCost"].Rows[i][3]);
                if (res > Configuration.mediancost)
                    break;
            }
            return res;
        }
        private int GetCostFromFormule()
        {
            int gruope_bad = 0;
            int aud_bad = 0;
            int teach_bad = 0;
            for (int i = 0; i < size; i++)
                for (int j = i + 1; j < size; j++)
                {
                    if (rozklad[i, 4] == rozklad[j, 4])
                    {
                        if (rozklad[i, 1] == rozklad[j, 1])
                            gruope_bad++;
                        if (rozklad[i, 2] == rozklad[j, 2])
                            teach_bad++;
                        if (rozklad[i, 3] == rozklad[j, 3])
                            aud_bad++;
                    }
                }
            int res = gruope_bad * 1000000;
            res += aud_bad * 1000000;
            res += teach_bad * 1000000;
            return res;
        }
        public int GetCost()  //TODO: dopysaty funkciju rahuvalku     //standart
        {
            return GetCostFromSelect();
        }


        /*dodatkovi*/
        internal void MoveToRes()
        {
            Configuration.resultsize = size;
            Configuration.result = rozklad;
        }

        internal int[,] GetRozklad()
        {
            return rozklad;
        }
        public int Ssize
        {
            get { return size; }
        }
    }
}
